home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / 80x0393.zip / ARGS.ASM < prev    next >
Assembly Source File  |  1993-06-20  |  6KB  |  186 lines

  1. ;---- args.asm ----------------------------------------------------------
  2. ; This file contains both an argument grabber and a simple heap.
  3. ;
  4. ; By: David Kirschbaum
  5. ;
  6. ; Args parses the command line into a unix-style parameter array.
  7. ; To use it, you should be a .COM program: that is,
  8. ; you must start your program as follows:
  9. ;       code    segment public 'CODE'
  10. ;       assume  CS:code,DS:code,ES:code
  11. ;       extrn   _Args:near,argc:word,argv:word          ;argc & argv in CS:
  12. ;
  13. ; and end the file as follows:
  14. ;       code    ends
  15. ;       end
  16. ; Link to your program with LINK YOURFILE,args; then EXE2BIN YOURFILE.
  17. ; Your program should start with an ORG 100H statement, and should
  18. ; CALL _Args to have it parse the cmdline.
  19. ; Argc and Argv are just as in C; argc = # of params on cmd line,
  20. ; argv is an array of pointers to strings (null terminated, of course).
  21. ; Because MS-DOS doesn't pass us the name used to invoke the program,
  22. ; argv[0] always points to a null string.
  23. ; _Shift updates ARGC.
  24. ;
  25. ; See the file \bin\asm\exist.asm for an example.
  26. ; Do not call NEW before calling _Args.
  27. ;
  28. ; Changes:
  29. ;   16 July 1984   DRK    Copy args out of default location; fixed argv[0].
  30. ;   1 Aug 1984     DRK    Added _Shift.
  31. ;   16 Oct 1984    MCN    _Shift updates argc
  32. ;   21 Mar 1985    DRK    oh yeah?
  33. ;Toad Hall Tweak
  34. ;--------------------------------------------------------------------------
  35.  
  36.         PUBLIC  _Args,ARGC,ARGV,_Shift, New, Dispose
  37.  
  38. ; Predeclared file handles
  39. STDIN   equ     0
  40. STDOUT  equ     1
  41. STDERR  equ     2
  42. STDSIO  equ     3
  43. STDPRN  equ     4
  44.  
  45. ; Maximum number of parameters
  46. MAXPARMS        equ     32
  47.  
  48. ; Declarations for accessing command line
  49. NCHAR   equ     80h             ; address of number of chars in argument line
  50. PARAMS  equ     81h             ; address of argument line
  51.  
  52. ;---- code starts here --------------------------------------------------------
  53. CSEG    segment public  'CODE'
  54.         assume CS:CSEG,ds:CSEG
  55.  
  56. _Args   proc    near
  57.         call    near ptr newinit
  58.         ; initialize
  59.         cld                     ; clear decrement mode
  60.         mov     bx, 2           ; argc = 0 (will sub 2 from bx at end)
  61.         mov     argv[0], offset null    ; prog name unknown; set to null.
  62.         mov     si, PARAMS      ; i = 0
  63.         mov     di, NCHAR
  64.         mov     cl, [di]        ; cx = # of chars in command line
  65.         xor     ch,ch
  66.         jcxz    Done            ; no arg chars -> we're done.
  67.         ; Allocate room for arguments; returns pointer in BX.
  68.         push    bx
  69.         push    cx
  70.         mov     cx, 128         ; worst case
  71.         call    New
  72.         mov     di, bx
  73.         pop     cx
  74.         pop     bx
  75.         ; Move arguments out of default DTA.
  76.         push    cx
  77.         push    di
  78.         rep     movsb
  79.         pop     si
  80.         pop     cx
  81.  
  82. ;Toad Hall:  When he's using redirection
  83. ;StdIn alone ("<") produces a command line length of 1 (space, CR)
  84. ;StdOut alone (">" : same result.
  85. ;StdIn and StdOut ("<wherever >wherever") produces a command line
  86. ;length of 2 (space, space, CR).
  87. ;A question mark alone would produce a command line length of 2
  88. ;(space, "?", CR).
  89.         ; Big loop- find arguments...
  90. ParmL:
  91.         ; Little loop #1: strip leading blanks from argument.
  92.         ; while (i<NCHAR && PARAMS[i] = ' ') do i++;
  93. StripL: lodsb                   ; al = [si++]
  94.         cmp     al, ' '         ; space?
  95.         loopz   StripL          ; if so, keep skipping.
  96.         jne     GotOne          ; If we found a nonblank, skip zero test.
  97.         jcxz    Done            ; found no unblank chars -> we're done.
  98. GotOne: dec     si              ; bump SI back to start of nonblank.
  99.         inc     cx
  100.         mov     argv[bx],si     ; save pointer to this string
  101.         ; Little loop #2: skip nonblank chars.
  102.         ; while (i<NCHAR && PARAMS[i] <> ' ') do i++;
  103. SkipL:  lodsb
  104.         cmp     al, ' '
  105.         loopnz  SkipL
  106.         jz      OkY
  107.                 ; Last char of line was not blank.
  108.          inc    si      ; make next statement put null AFTER arg.
  109. OkY:    mov     byte ptr [si][-1], 0    ; put null at end of arg
  110.         add     bx,2            ; argc++;
  111.         jcxz    Done            ; if we ran off end of cmdline, no more args.
  112.          cmp    bx, MAXPARMS*2
  113.          jb     ParmL           ; loop if argc < MAXPARMS.
  114. Done:   ; All done finding parms; now share argc with caller.
  115.         sub     bx, 2
  116.         shr     bx, 1
  117.         mov     argc, bx
  118.         ret
  119. _Args   endp
  120.  
  121. ;---- _Shift: --------------------------------------------
  122. ; Shifts %2 to %1, %3 to %2, etc.  Leaves %0 alone.
  123. ; Works by shuffling argv[*].
  124. _Shift  proc    near
  125.         cld
  126.         mov     si, offset argv[4]
  127.         mov     di, offset argv[2]
  128.         mov     cx, MAXPARMS
  129.         rep     movsw
  130. ; wrongo!  Caller should do this...
  131. ;       sub argc, 1             ; there is now one less argument
  132.         ret
  133. _Shift  endp
  134.  
  135. ;----- Newinit- initialize heap
  136.  
  137. Newinit proc    near
  138.         mov     CS:firstfree, offset lastcode
  139.         ret
  140. Newinit endp
  141.  
  142. ; Given length in CX, returns pointer in BX.
  143. ; Does not affect CX.
  144. New     proc    near
  145.         push    cx
  146.         mov     bx, CS:firstfree
  147.         add     cx, CS:firstfree
  148.         mov     CS:firstfree, cx
  149.         cmp     sp, cx
  150.         pop     cx
  151.         jbe     Newerror
  152.         ret
  153.  
  154. stackmsg        db      '?New: heap overflow', 7, 13, 10
  155. Newerror:
  156. SML     equ     Newerror - stackmsg
  157.         push    cs
  158.         pop     ds
  159.         mov     dx, offset stackmsg
  160.         mov     cx, SML
  161.         mov     bx, STDERR
  162.         mov     ah, 40h
  163.         int     21h
  164.         mov     ax, 4c02h               ; terminate- error code 2
  165.         int     21h
  166. New     endp
  167.  
  168. ;---- Call Dispose with ptr in BX, length in CX.
  169. Dispose proc    near
  170.         ret
  171. Dispose endp
  172.  
  173. ;------ Heap variables ------
  174. firstfree       dw      ?
  175.  
  176. ;---- parameter count, array ------------------------------------
  177. ; Pointers to up to MAXPARMS parameter strings are held here.
  178.  
  179. null    dw      0               ; the null string
  180. argc    dw      ?
  181. argv    dw      MAXPARMS dup (?)
  182. lastcode        label   near
  183.  
  184. CSEG    ends
  185.         end
  186.